package cn.neusoft.service.impl;

import cn.neusoft.domain.Dept;
import cn.neusoft.enums.Constants;
import cn.neusoft.enums.Status;
import cn.neusoft.exception.AppException;
import cn.neusoft.exception.AppExceptionCodeMsg;
import cn.neusoft.mapper.DeptMapper;
import cn.neusoft.query.BaseQuery;
import cn.neusoft.query.DeptQuery;
import cn.neusoft.service.DeptService;
import cn.neusoft.util.EnumUtils;
import cn.neusoft.vo.PageBean;
import cn.neusoft.vo.TreeSelect;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    DeptMapper deptMapper;

    /**
     * 新增部门
     *
     * @param dept
     */
    @Transactional
    @Override
    public void add(Dept dept) {
        // 状态参数非法
        if (!EnumUtils.isInclude(Status.class, dept.getStatus())) {
            throw new AppException(AppExceptionCodeMsg.DEPT_STATUS_INVALID);
        }
        // 部门名称重复(在同一父级部门下)
        if (deptMapper.checkDeptNameUnique(dept) != null) {
            throw new AppException(AppExceptionCodeMsg.DEPT_NAME_DUPLICATED);
        }
        Dept parent_dept = deptMapper.findById(dept.getParent_id());
        // 父部门不存在
        if (parent_dept == null) {
            throw new AppException(AppExceptionCodeMsg.DEPT_PARENT_NOT_EXITS);
        }

        // 当前部门的祖先列表 = 父部门的祖先列表 + 父部门id
        dept.setAncestors(parent_dept.getAncestors() + "," + dept.getParent_id());

        // 父部门当前的子部门数量
        int cur_childNum = deptMapper.hasChildById(parent_dept.getDept_id());
        // 当前部门的order_num = 父部门当前的子部门数 + 1
        dept.setOrder_num(cur_childNum + 1);

        deptMapper.add(dept);
    }

    /**
     * 修改部门信息
     *
     * @param dept
     */
    @Transactional
    @Override
    public void update(Dept dept) {
        // 状态参数非法
        if (!EnumUtils.isInclude(Status.class, dept.getStatus())) {
            throw new AppException(AppExceptionCodeMsg.DEPT_STATUS_INVALID);
        }
        // 不存在id为传入值的部门
        if (deptMapper.findById(dept.getDept_id()) == null) {
            throw new AppException(AppExceptionCodeMsg.DEPT_NOT_EXISTS);
        }
        // 修改的名称与其他部门重复（统一父部门下）【注意要排除自己,防止部门名未修改时出错】
        Dept sameNameDept = deptMapper.checkDeptNameUnique(dept);
        if (sameNameDept != null
                && !Objects.equals(sameNameDept.getDept_id(), dept.getDept_id())) {
            throw new AppException(AppExceptionCodeMsg.DEPT_NAME_DUPLICATED);
        }
        Dept parent_dept = deptMapper.findById(dept.getParent_id());
        // 父部门不存在
        if (parent_dept == null) {
            throw new AppException(AppExceptionCodeMsg.DEPT_PARENT_NOT_EXITS);
        }

        // 当前部门的祖先列表 = 父部门的祖先列表 + 父部门id
        dept.setAncestors(parent_dept.getAncestors() + "," + dept.getParent_id());

        // 父部门当前的子部门数量
        int cur_childNum = deptMapper.hasChildById(parent_dept.getDept_id());
        // 当前部门的order_num = 父部门当前的子部门数 + 1
        dept.setOrder_num(cur_childNum + 1);

        deptMapper.update(dept);
    }

    @Override
    public void updateStatus(Dept dept) {

    }


    /**
     * 删除部门
     *
     * @param dept_id
     */
    @Transactional
    @Override
    public void deleteById(Long dept_id) {
        // 当前部门存在子部门，不能删除
        if (deptMapper.hasChildById(dept_id) > 0) {
            throw new AppException(AppExceptionCodeMsg.DEPT_DELETE_HASCHILD);
        }
        deptMapper.deleteById(dept_id);
    }

    /**
     * 查询所有部门的信息
     *
     * @return
     */
    @Transactional
    @Override
    public List<Dept> findAll() {
        return deptMapper.findAll();
    }

    /**
     * 根据id查询部门信息
     *
     * @param dept_id
     * @return
     */
    @Transactional
    @Override
    public Dept findById(Long dept_id) {
        return deptMapper.findById(dept_id);
    }

//    @Override
//    public boolean hasChildById(Long dept_id) {
//        return deptMapper.hasChildById(dept_id) > 0;
//    }

    /**
     * 分页条件查询
     *
     * @param query
     * @return
     */
    @Transactional
    @Override
    public PageBean<Dept> findByPage(BaseQuery query) {
        // 构建结果对象
        PageBean<Dept> pageBean = new PageBean<>();

        // 开启分页
        PageHelper.startPage(query.getPageNow(), query.getPageSize());

        // 查询得到当前页的集合
        List<Dept> deptList = deptMapper.findByCondition(query);

        // 创建一个分页的实体PageInfo
        PageInfo<Dept> pageInfo = new PageInfo<>(deptList);

        pageBean.setTotalRows(pageInfo.getTotal());
        pageBean.setTotalPages(pageInfo.getPages());
        pageBean.setRowData(pageInfo.getList());

        return pageBean;
    }

    @Transactional
    @Override
    public List<Dept> getDeptTreeList() {
        List<Dept> deptList = deptMapper.findAll();

        return buildDeptTree(deptList);
    }

    /**
     * 返回所有正常部门的级联下拉列表
     *
     * @return
     */
    @Transactional
    @Override
    public List<TreeSelect> getNormalDeptTreeSelect() {

        DeptQuery query = new DeptQuery();
        query.setStatus(Status.OK.getCode());

        // 查询得到所有正常部门
        List<Dept> deptList = deptMapper.findByCondition(query);

        // 构建树结构
        List<Dept> deptTree = buildDeptTree(deptList);

        // 返回前端需要的级联下拉列表结构
        return deptTree.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 根据分库id，得到其下属的所有正常分站的级联下拉列表
     *
     * @return
     */
    @Transactional
    @Override
    public List<TreeSelect> getNormalSubstationTreeSelect() {

        DeptQuery query = new DeptQuery();
        query.setStatus(Status.OK.getCode());
//        query.setParent_id(warehouse_id);

        // 查询得到所有正常部门
        List<Dept> deptList = deptMapper.findByCondition(query);

        // 得到所有正常的分站列表
        List<Dept> substationList = deptList.stream()
                .filter(dept -> Objects.equals(dept.getParent_id(), Constants.SUB_WAREHOUSE_PARENT_ID.getCode()))
                .flatMap(dept -> deptList.stream()
                        .filter(subDept -> Objects.equals(subDept.getParent_id(), dept.getDept_id())))
                .collect(Collectors.toList());

        return substationList.stream().map(TreeSelect::new).collect(Collectors.toList());

    }

    /**
     * 返回所有正常分库的级联下拉列表
     *
     * @return
     */
    @Transactional
    @Override
    public List<TreeSelect> getNormalSubWarehouseTreeSelect() {

        DeptQuery query = new DeptQuery();
        query.setStatus(Status.OK.getCode());
        query.setParent_id(Constants.SUB_WAREHOUSE_PARENT_ID.getCode());

        // 查询得到所有正常仓库
        List<Dept> deptList = deptMapper.findByCondition(query);

        // 构建树结构
        List<Dept> deptTree = buildDeptTree(deptList);

        // 返回前端需要的级联下拉列表结构
        return deptTree.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

//    @Transactional
//    @Override
//    public List<Dept> getAllSubstations() {
//        DeptQuery query = new DeptQuery();
//        query.setParent_id(Constants.SUBSTATION_PARENT_ID.getCode());
//
//        return deptMapper.findByCondition(query);
//    }
//
//    @Transactional
//    @Override
//    public List<Dept> getAllWarehouses() {
//        DeptQuery query = new DeptQuery();
//        query.setParent_id(Constants.WAREHOUSE_PARENT_ID.getCode());
//
//        return deptMapper.findByCondition(query);
//    }


    /**
     * 构建前端所需要树结构
     *
     * @param deptList 部门列表
     * @return 树结构列表
     */
    private List<Dept> buildDeptTree(List<Dept> deptList) {
        List<Dept> returnList = new ArrayList<>();
        List<Long> idList = deptList.stream().map(Dept::getDept_id).collect(Collectors.toList());
        for (Dept dept : deptList) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!idList.contains(dept.getParent_id())) {
                recursionFn(deptList, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty()) {
            returnList = deptList;
        }
        return returnList;
    }

    /**
     * 得到目标部门的子部门列表
     */
    private List<Dept> getChildList(List<Dept> list, Dept t) {
        List<Dept> tlist = new ArrayList<>();
        for (Dept n : list) {
            if (!StringUtils.isEmpty(n.getParent_id())
                    && Objects.equals(n.getParent_id(), t.getDept_id())
            ) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<Dept> list, Dept t) {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 递归列表
     * 结束条件为所遍历的节点无下一级节点
     */
    private void recursionFn(List<Dept> list, Dept t) {
        // 得到子节点列表
        List<Dept> childList = getChildList(list, t);
        t.setChildren(childList);
        for (Dept tChild : childList) {
            // 如果子节点有下一级节点，得到下一级的节点列表
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }
}
